<?php

namespace App\Http\Controllers\Admin\Config;

use App\Http\Controllers\AdminController;
use App\Models\Admin\Permission;
use Auth;
use DB;
use Illuminate\Http\Request;
use Log;
use Validator;

class PermissionController extends AdminController
{
    /**
     * 验证权限路径唯一
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function checkName(Request $request)
    {
        DB::connection()->enableQueryLog();
        $name = $request->input('name');
        $id   = $request->input('id');
        $this->checkUniqueName($id, $name);
        $this->ajaxJson(0, '');
    }

    /**
     * 新增数据
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function insertOne(Request $request)
    {
        $validator = $this->formValidator($request->all());
        if ($validator->fails()) {
            $this->ajaxJson(1, $validator->errors()->first());
        }
        $id = $request->input('id');
        if ($id > 0) {
            $this->ajaxJson(0, '方式错误,无法更新数据,只能新增数据');
        }
        $name = $request->input('name');
        $pid  = $request->input('pid');
        $this->checkUniqueName($id, $name);
        $lft = $level = $root_pid = 0;
        //添加子节点,获取父节点的左值和右值
        if ($pid) {
            $parentPermission = $this->_get_one($pid);
            $lft              = $parentPermission->lft;
            $level            = $parentPermission->level;
            $root_pid         = $parentPermission->root_pid;
        }
        $displayName = $request->input('displayName');

        $permission                  = new Permission();
        $permission->name            = $name;
        $permission->displayName     = $displayName;
        $permission->root_pid        = $root_pid;
        $permission->pid             = $pid;
        $permission->lft             = $lft + 1;
        $permission->rgt             = $lft + 2;
        $permission->level           = $level + 1;

        try {
            DB::connection()->enableQueryLog();
            DB::beginTransaction();
            Permission::where('root_pid', $root_pid)->where('lft', '>', $lft)->increment('lft', 2);
            Permission::where('root_pid', $root_pid)->where('rgt', '>', $lft)->increment('rgt', 2);
            $permission->save();
            if (!$pid) {
                Permission::where('id', $permission->id)->update(['root_pid' => $permission->id]);
            }
            DB::commit();
            $this->ajaxJson(0, '权限添加成功');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('【' . $e->getMessage() . '】' . '【' . $e->getFile() . '】' . '【' . $e->getTraceAsString() . '】');
            $this->ajaxJson(1, '权限添加失败');
        }
    }

    /**
     * 更新单条数据
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function postOne(Request $request)
    {
        $validator = $this->formValidator($request->all());
        if ($validator->fails()) {
            $this->ajaxJson(1, $validator->errors()->first());
        }
        $name = $request->input('name');
        $id   = $request->input('id');
        $this->checkUniqueName($id, $name);
        if (!$id) {
            $this->ajaxJson(0, '方式错误,无法新增数据,只能更新数据');
        }

        try {
            DB::beginTransaction();
            DB::connection()->enableQueryLog();
            $permission = $this->_get_one($id);
            DB::table('permission')->where('id', $id)->update([
                'name'            => $name,
                'displayName'     => $request->input('displayName'),
                'updated_at'      => date('Y-m-d H:i:s'),
            ]);
            DB::commit();
            $this->ajaxJson(0, '权限更新成功');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('【' . $e->getMessage() . '】' . '【' . $e->getFile() . '】' . '【' . $e->getTraceAsString() . '】');
            $this->ajaxJson(1, '权限更新失败');
        }
    }
    

    /**
     * 删除单条数据
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function deleteOne($id, Request $request)
    {
        $permission = $this->_get_one($id);
        //有角色使用该权限
        $count = DB::table('role_permission')->where('permission_id', $id)->count();
        if ($count > 0) {
            $this->ajaxJson(1, '已有' . $count . '种角色使用删除的权限,无法删除。请将使用该权限的角色,删除该权限');
        }

        $request->offsetSet('id', $id);

        //获取当前节点下所有的子节点
        $childrens      = DB::table('permission')->where('root_pid', $permission->root_pid)->where('lft', '>', $permission->lft)->where('rgt', '<', $permission->rgt)->get()->toArray();
        $childrenCount  = 1; //子节点个数,自己算一个节点
        $childrensIdArr = [];
        if (!empty($childrens)) {
            $childrensIdArr = array_pluck($childrens, 'id');
            $childrenCount  = count($childrens) + 1;
        }
        //追加本身节点
        $childrensIdArr[] = $permission->id;
        try {
            DB::connection()->enableQueryLog();
            DB::beginTransaction();
            DB::table('permission')->whereIn('id', $childrensIdArr)->delete();
            DB::table('permission')->where('root_pid', $permission->root_pid)->where('lft', '>', $permission->lft)->decrement('lft', 2 * $childrenCount);
            DB::table('permission')->where('root_pid', $permission->root_pid)->where('rgt', '>', $permission->lft)->decrement('rgt', 2 * $childrenCount);
            DB::commit();
            $this->ajaxJson(0, '删除成功');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('【' . $e->getMessage() . '】' . '【' . $e->getFile() . '】' . '【' . $e->getTraceAsString() . '】');
            $this->ajaxJson(1, '删除失败');
        }
    }

    /**
     * 获取树形结构数据
     * @return [type] [description]
     */
    public function getTree(Request $request)
    {
        DB::connection()->enableQueryLog();
        $model = Permission::select(
            'permission.id',
            'permission.name',
            'permission.displayName',
            'permission.pid',
            'permission.created_at',
            'permission.updated_at'
        );
        
        $name = $request->input('name');

        if ($name) {
            $model->where('name', 'like', '%' . $name . '%')->orWhere('displayName', 'like', '%' . $name . '%');
        }
        $getData = $model->get()->toArray();
        $data    = [];
        //将获得数据重新插入数组,以数据的ID为下标
        foreach ($getData as $value) {
            $data[$value['id']] = $value;
        }
        $parent = array();

        //模糊查询,根据查询结果,递归到父节点,产生节点数据,和正常展示不同,不是递归到子节点
        if ($name) {
            //获取所有搜索结果的父节点
            foreach ($data as $permission) {
                $this->getParent($permission['pid'], $data);
            }
        }
        foreach ($data as $key => $value) {
            if (!$value['pid']) {
                $parent[] = $value;
                unset($data[$key]);
            }
        }

        foreach ($parent as $key => $value) {
            $result = $this->formatTreeData($data, $value['id']);
            if ($result) {
                $parent[$key]['children'] = $result;
                $parent[$key]['expand']   = true;
            }
        }
        $this->ajaxJson(0, '', $parent);
    }


    /**
     * 获取父节点数据
     * @return [type] [description]
     */
    private function getParent($pid, &$data)
    {
        if ($pid == 0) {
            return $data;
        }
        $permission = Permission::find($pid)->toArray();
        //将获得的父节点数据加入数组中
        if (!isset($data[$permission['id']])) {
            $data[$permission['id']] = $permission;
        }
        if (!$permission['pid']) {
            return $data;
        } else {
            $this->getParent($permission['pid'], $data);
        }
    }

    /**
     * 格式化树形数据
     * @param  [type] $data [description]
     * @param  [type] $pid  [description]
     * @return [type]       [description]
     */
    private function formatTreeData($data, $pid)
    {
        $list = array();
        foreach ($data as $key => $value) {
            if ($value['pid'] == $pid) {
                $result = $this->formatTreeData($data, $value['id']);
                if (!empty($result) && count($result) > 0) {
                    $value['children'] = $result;
                    $value['expand']   = true;
                }
                $list[] = $value;
            }
        }
        return $list;
    }

    /**
     * 验证权限名唯一
     * @param  [type] $id   [description]
     * @param  [type] $name [description]
     * @return [type]       [description]
     */
    private function checkUniqueName($id, $name)
    {
        $count = Permission::where('id', '!=', $id)->where('name', $name)->count();
        if ($count > 0) {
            $this->ajaxJson(1, '存在相同的路径');
        }
    }

    /**
     * 表单验证
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    private function formValidator(array $data)
    {
        $attribute = array(
            'id'          => '编号',
            'name'        => '路径地址',
            'pid'         => '父节点',
            'displayName' => '权限名称',
        );

        return Validator::make($data, [
            'id'          => 'bail|required|numeric',
            'name'        => 'bail|required',
            'pid'         => 'bail|required|numeric',
            'displayName' => 'bail|required',
        ], [], $attribute);
    }

    /**
     * 公共获取单条数据
     * @return [type] [description]
     */
    private function _get_one($id)
    {
        $permission = Permission::find($id);
        if (!$permission) {
            $this->ajaxJson(1, '数据不存在,请刷新页面');
        }
        return $permission;
    }
}
